<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8"> <title>Lass</title> <meta name="viewport" content="width=device-width"> <meta name="description" content="Lisp Augmented Style Sheets. Compiles LASS to CSS."> <meta name="author" content="Nicolas Hafner &lt;shinmera@tymoon.eu&gt;"> <style type="text/css"> body{
          max-width: 1024px;
          margin: 0 auto 0 auto;
          font-family: sans-serif;
          color: #333333;
          font-size: 14pt;
          padding: 5px;
      }
      body>header{
          display:flex;
          align-items: center;
          justify-content: center;
          flex-direction: column;
          max-width: 100%;
          text-align: center;
      }
      body>header img{
          max-width: 50%;
      }
      img{
          max-width: 100%;
          max-height: 100%;
      }
      code{
          font-family: Consolas, Inconsolata, monospace;
      }
      a{
          text-decoration: none;
          color: #0055AA;
      }
      a img{
          border: none;
      }
      #documentation{
          text-align: justify;
      }
      #documentation pre{
          margin-left: 20px;
          overflow: auto;
      }
      #documentation img{
          margin: 5px;
      }
      #symbol-index>ul{
          list-style: none;
          padding: 0;
      }
      #symbol-index .package>ul{
          list-style: none;
          padding: 0 0 0 10px;
      }
      #symbol-index .package .nicknames{
          font-weight: normal;
      }
      #symbol-index .package h4{
          display: inline-block;
          margin: 0;
      }
      #symbol-index .package article{
          margin: 0 0 15px 0;
      }
      #symbol-index .package article header{
          font-size: 1.2em;
          font-weight: normal;
      }
      #symbol-index .package .name{
          margin-right: 5px;
      }
      #symbol-index .package .docstring{
          margin: 0 0 0 15px;
          white-space: pre-wrap;
          font-size: 12pt;
      }
      @media (max-width: 800px){
          body{font-size: 12pt;}
      } </style> </head> <body> <header> <h1>lass</h1> <span class="version">0.5.0</span> <p class="description">Lisp Augmented Style Sheets. Compiles LASS to CSS.</p> </header> <main> <article id="documentation">  <div><h2 id="about_lass">About LASS</h2> <p>Writing CSS files comes with a lot of repetition and is generally much too verbose. With lispy syntax, shortcuts, and improvements, LASS aims to help you out in writing CSS quick and easy. LASS was largely inspired by <a href="http://sass-lang.com/">SASS</a>.</p> <h2 id="how_to_&amp;_examples">How To &amp; Examples</h2> <p>LASS supports two modes, one being directly in your lisp code, the other in pure LASS files. Adding LASS into your code is easy:</p> <pre><code>(<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
 '(div
   :background black))

&quot;div{
    background: black;
}&quot;
</code></pre> <p>LASS works on the following simple principles: A list is a block. The first argument in the list is a selector. The body of the list makes up the properties and sub-blocks. A property is started with a keyword that is used as the property name. Following is a bunch of property arguments until a new keyword, list, or the end is reached. A list inside a block is, again, a block with the twist that the parent block's selector is prepended to the sub-block's selector.</p> <pre><code>(<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
 '(nav
   (ul
    :list-style none
    (li
     :margin 0 :padding 0
     :display inline-block)))))

&quot;nav ul{
    list-style: none;
}

nav ul li{
    margin: 0;
    padding: 0;
    display: inline-block;
}&quot;
</code></pre> <p>Since LASS' <code><a href="#LASS:COMPILE-SHEET">COMPILE-SHEET</a></code> simply takes a bunch of lists as its argument, you can use the backquote and comma to integrate variables from your lisp environment:</p> <pre><code>(<a href="http://l1sp.org/cl/let">let</a> ((color &quot;#0088EE&quot;))
  (<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
   `(div
     :background ,color))))

&quot;div{
    background: #0088EE;
}&quot;
</code></pre> <p>Alternatively however, and this is especially useful in pure LASS files, you can use the <code><a href="http://l1sp.org/cl/let">LET</a></code> block to create LASS-specific bindings:</p> <pre><code>(<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
 '(:let ((color &quot;#0088EE&quot;))
   (div
    :background #(color))))

&quot;div{
    background: #0088EE;
}&quot;
</code></pre> <p>LASS' selector mechanism is very flexible and allows for some complex logic to reduce duplication:</p> <pre><code>(<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
 '(article
   ((:or p blockquote)
    :margin 0 :padding 0

    (a
     :color black)

    ((:and a :hover)
     :color darkred))))

&quot;article p, article blockquote{
    margin: 0;
    padding: 0;
}

article p a, article blockquote a{
    color: black;
}

article p a:hover, article blockquote a:hover{
    color: darkred;
}&quot;
</code></pre> <p>But it can go even further:</p> <pre><code>(<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
 '((:and
    (:or article section)
    (:= data-author (:or yukari ran chen))
    (:nth-child (:or 1 2 3)))
   :display none))

&quot;article[data-author=\&quot;yukari\&quot;]:nth-child(1),
 article[data-author=\&quot;yukari\&quot;]:nth-child(2),
 article[data-author=\&quot;yukari\&quot;]:nth-child(3),
 article[data-author=\&quot;ran\&quot;]:nth-child(1),
 article[data-author=\&quot;ran\&quot;]:nth-child(2),
 article[data-author=\&quot;ran\&quot;]:nth-child(3),
 article[data-author=\&quot;chen\&quot;]:nth-child(1),
 article[data-author=\&quot;chen\&quot;]:nth-child(2),
 article[data-author=\&quot;chen\&quot;]:nth-child(3),
 section[data-author=\&quot;yukari\&quot;]:nth-child(1),
 section[data-author=\&quot;yukari\&quot;]:nth-child(2),
 section[data-author=\&quot;yukari\&quot;]:nth-child(3),
 section[data-author=\&quot;ran\&quot;]:nth-child(1),
 section[data-author=\&quot;ran\&quot;]:nth-child(2),
 section[data-author=\&quot;ran\&quot;]:nth-child(3),
 section[data-author=\&quot;chen\&quot;]:nth-child(1),
 section[data-author=\&quot;chen\&quot;]:nth-child(2),
 section[data-author=\&quot;chen\&quot;]:nth-child(3){
    display: none;
}&quot;
</code></pre> <p>Whoa nelly!</p> <p>Some CSS properties are not fully specified yet and require browser-specific prefixes. LASS can help you with that, too:</p> <pre><code>(<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
 '(.fun
   :linear-gradient &quot;deg(45)&quot; black 0% darkgray 100%
   :transform rotate -45deg))

&quot;.fun{
    background: -moz-linear-gradient(deg(45), black 0%, darkgray 100%);
    background: -o-linear-gradient(deg(45), black 0%, darkgray 100%);
    background: -webkit-linear-gradient(deg(45), black 0%, darkgray 100%);
    background: -ms-linear-gradient(deg(45), black 0%, darkgray 100%);
    background: linear-gradient(deg(45), black 0%, darkgray 100%);
    -moz-transform: rotate(-45deg);
    -o-transform: rotate(-45deg);
    -webkit-transform: rotate(-45deg);
    -ms-transform: rotate(-45deg);
    transform: rotate(-45deg);
}&quot;
</code></pre> <p>LASS also supports the various <code>@QUERY</code> operator blocks:</p> <pre><code>(<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
 '(:media &quot;(max-width: 800px)&quot;
   (div
    :margin 0)))

&quot;@media (max-width: 800px){
    div{
        margin: 0;
    }
}&quot;
</code></pre> <p>By default LASS activates pretty-printing and inserts newlines and spaces where appropriate in order to make the result readable and easy to debug. However, you can also deactivate that and directly produce minified CSS:</p> <pre><code>(<a href="http://l1sp.org/cl/let">let</a> (<a href="#LASS:*PRETTY*">(lass:*pretty*</a> NIL))
  (<a href="#LASS:COMPILE-AND-WRITE">lass:compile-and-write</a>
   '(:media &quot;(max-width: 800px)&quot;
     (div
      :margin 0))))

&quot;@media (max-width: 800px){div{margin:0;}}&quot;
</code></pre> <p>As mentioned above you can write pure LASS files to compile down to a CSS file. To do that, simply use <code><a href="#LASS:GENERATE">GENERATE</a></code>:</p> <p><img src="http://shinmera.tymoon.eu/public/screenshot-2014.09.04-23:57:38.png" alt="generate-example"></p> <h2 id="blocks">Blocks</h2> <p>Each block in a LASS sheet consists of a list containing a selector followed by one or more properties or sub-blocks. </p> <pre><code>(selector [property | block]*)
</code></pre> <h2 id="selectors">Selectors</h2> <p>The following list contains examples for the various uses of selectors.</p> <ul> <li>Any element<br> <code>*</code></li> <li>An element with tag-name <code>e</code><br> <code>e</code></li> <li>An element with tag-name <code>e</code> or <code>f</code><br> <code>(:or e f)</code></li> <li>An <code>e</code> element with the <code>:link</code> pseudo-selector<br> <code>(:and e :link)</code></li> <li>The first formatted line of an <code>e</code> element<br> <code>(:and e |::first-line|)</code> or <code>(:and e &quot;::first-line&quot;)</code></li> <li>An <code>e</code> element with a &quot;warning&quot; class<br> <code>e.warning</code></li> <li>An <code>e</code> element with ID equal to <code><a href="http://l1sp.org/cl/warning">warning</a></code><br> <code>|e#warning|</code> or <code>&quot;e#warning&quot;</code></li> <li>An <code>e</code> element with a <code>foo</code> attribute<br> <code>e[foo]</code></li> <li>An <code>e</code> element whose <code>foo</code> attribute value is exactly equal to <code>bar</code><br> <code>(:and :a (:= foo &quot;bar&quot;))</code></li> <li>An <code>e</code> element whose <code>foo</code> attribute value is a list of whitespace-separated values, one of which is exactly equal to <code>bar</code><br> <code>(:and :a (:~= foo &quot;bar&quot;))</code></li> <li>An <code>e</code> element whose <code>foo</code> attribute has a hyphen-separated list of values beginning (from the left) with <code>bar</code><br> <code>(:and :a (:/= foo &quot;bar&quot;))</code></li> <li>An <code>e</code> element whose <code>foo</code> attribute value begins exactly with the string <code>bar</code><br> <code>(:and :a (:^= foo &quot;bar&quot;))</code></li> <li>An <code>e</code> element whose <code>foo</code> attribute value ends exactly with the string <code>bar</code><br> <code>(:and :a (:$= foo &quot;bar&quot;))</code></li> <li>An <code>e</code> element whose <code>foo</code> attribute value contains the substring <code>bar</code><br> <code>(:and :a (:*= foo &quot;bar&quot;))</code></li> <li>An <code>e</code> element that matches the pseudo-selector <code>nth-child(2)</code><br> <code>(e (:nth-child 2))</code></li> <li>An <code>f</code> element preceded by an <code>e</code> element<br> <code>(e ~ f)</code></li> <li>An <code>f</code> element immediately precede by an <code>e</code> element<br> <code>(e + f)</code></li> <li>An <code>f</code> element which is a descendant of <code>e</code><br> <code>(e f)</code></li> <li>An <code>f</code> element which is a direct descendant of <code>e</code><br> <code>(e &gt; f)</code></li> </ul> <h2 id="selector_combinations">Selector Combinations</h2> <p>As illustrated briefly above, LASS includes two combinators for selectors, <code>:and</code> and <code>:or</code>. These combinators are <em>combinatoric</em>, meaning that all possible combinations are explored. Consider the following selector:</p> <pre><code>((foo (:and a .title (:or :active :hover)) (:or span div)))
</code></pre> <p>Enumerating all possible answers to this combination would result in the following list</p> <pre><code>foo a.title:active span
foo a.title:active div
foo a.title:hover span
foo a.title:hover div
</code></pre> <p>The number of possible combinations can quickly explode in size the more options are available. This means that for complex relations and expressions, LASS can be extremely concise. Note that combinators are available at any position in a selector, this includes the arguments of a pseudo-selector like <code>:nth-child</code>.</p> <h2 id="properties">Properties</h2> <p>A property consists of a keyword symbol and a sequence of values. The values to a property are gathered up until either a non-value list or a new keyword is encountered. Originally it stopped as soon as a list was encountered, but this behaviour was changed and specially recognised lists are integrated to allow a more native look for certain values like colours, urls, and so on. Certain properties are specifically declared and will error if they are passed the wrong number or invalid kind of values. For most however, LASS will just blindly put things into the CSS file as you give them. It is up to you to make sure that the values are valid.</p> <pre><code>:text-style underline
:color (rgb 212 112 30)
:background (url &quot;/foo&quot;)
:border 1px solid black
</code></pre> <p>Certain properties currently still require vendor-specific declarations. LASS tries to do that automatically for you, but it also needs to know about these declarations and as such, they need to be manually added. Some of the more common ones are included in LASS by default, but if you encounter one that isn't, you are welcome to send a pull request (see Extending LASS on how to do it).</p> <h2 id="sub-blocks">Sub-Blocks</h2> <p>A block can contain other blocks. These sub-blocks are recursively flattened into the structure by simply prepending the selector of the parent block. Thus</p> <pre><code>(foo (bar (baz) (bam)))
</code></pre> <p>Is equivalent to</p> <pre><code>(foo) ((foo bar)) ((foo bar baz)) ((foo bar bam))
</code></pre> <p>Allowing this kind of nesting allows you to more closely mirror the structure present in your HTML file that you want to style. Combining this with the selector combinations, this system allows reducing code duplication a lot.</p> <h2 id="special_blocks">Special Blocks</h2> <p>In CSS3 there are special properties and blocks that are preceded by an <code>@</code> symbol. The most well-known examples therefore are probably <code>@include</code> and <code>@media</code>. LASS implements all of these special blocks by a keyword symbol equivalent selector. Therefore the above two would translate to the following in LASS.</p> <pre><code>(:include (url &quot;foo&quot;))
(:media &quot;(max-width: 800px)&quot;
 (foo))
</code></pre> <h2 id="variables">Variables</h2> <p>Often times it is useful to define variables that you can use within your style so that colours and fonts can quickly be exchanged. LASS allows you to do that too using the <code>:let</code> directive and by abusing the vector type. It is probably best illustrated using an example:</p> <pre><code>(:let ((foo &quot;#0088EE&quot;))
  ((a:active) :color #(foo)))
</code></pre> <h2 id="extending_lass">Extending LASS</h2> <p>Pretty much every part of LASS is extensible through methods. Most useful will however probably be the <code><a href="#LASS:DEFINE-SPECIAL-PROPERTY">DEFINE-SPECIAL-PROPERTY</a></code>, <code><a href="#LASS:DEFINE-BROWSER-PROPERTY">DEFINE-BROWSER-PROPERTY</a></code> and <code><a href="#LASS:DEFINE-SPECIAL-SELECTOR">DEFINE-SPECIAL-SELECTOR</a></code> helper-macros. Here's some examples from the <code>SPECIAL.LISP</code> file that defines some standard special handlers:</p> <pre><code>(<a href="#LASS:DEFINE-SPECIAL-PROPERTY">define-special-property</a> font-family (<a href="http://l1sp.org/cl/&amp;rest">&amp;rest</a> faces)
  (<a href="http://l1sp.org/cl/list">list</a> (<a href="#LASS:MAKE-PROPERTY">make-property</a> &quot;font-family&quot; (<a href="http://l1sp.org/cl/format">format</a> NIL &quot;~{~a~^, ~}&quot; (<a href="http://l1sp.org/cl/mapcar">mapcar</a> #'resolve faces)))))

(<a href="#LASS:DEFINE-BROWSER-PROPERTY">define-browser-property</a> linear-gradient (direction &amp;rest colors)
  (:default (property)
    (<a href="#LASS:MAKE-PROPERTY">make-property</a> &quot;background&quot; (<a href="http://l1sp.org/cl/format">format</a> NIL &quot;~a(~a~{, ~a ~a~})&quot;
                                         property (<a href="#LASS:RESOLVE">resolve</a> direction) (<a href="http://l1sp.org/cl/mapcar">mapcar</a> #'resolve colors)))))
</code></pre> <p>For more control, have a look at the various <code>COMPILE-*</code> generic functions.</p> <h2 id="emacs_support">Emacs Support</h2> <p>LASS includes a tiny elisp file, <code>lass.el</code>. Add LASS' directory to your emacs <code>LOAD-PATH</code> and <code><a href="http://l1sp.org/cl/require">REQUIRE</a></code> lass.</p> <pre><code>(add-to-list 'load-path &quot;[path-to-lass-source-dir]/&quot;)
(<a href="http://l1sp.org/cl/require">require</a> 'lass)
</code></pre> <p>Once you visit a <code>.lass</code> file, it will automatically start in the <code>LASS</code> major-mode, which is a derived-mode from <code>COMMON-LISP-MODE</code>. Whenever you save, it will automatically try to compile the lass file to its CSS equivalent. If slime is connected, it will try to quickload LASS and evaluate <code><a href="#LASS:GENERATE">GENERATE</a></code>. If slime is not connected, it instead executes a shell command. In order for that to work, the <a href="https://github.com/Shinmera/LASS/releases"><code>lass</code> binary</a> must be in your path.</p> <p>If your operating system is not directly supported with a binary, you can build it yourself using a build tool like <a href="http://www.xach.com/lisp/buildapp/">Buildapp</a>, the ASDF system <code>BINARY-LASS</code> and the entry-point <code>BINARY-LASS:CMD-WRAPPER</code>.</p> <h2 id="asdf_integration">ASDF Integration</h2> <p>If you want to compile LASS files to CSS in your systems, you can now (v0.4+) do this via a <code><a href="#LASS:LASS-FILE">lass-file</a></code> component type, and <code>:defsystem-depends-on</code>-ing LASS.</p> <pre><code>(asdf:defsystem my-system
  :defsystem-depends-on (:lass)
  :components (<a href="#LASS:LASS-FILE">(:lass-file</a> &quot;test-file&quot;)))
</code></pre> <p>You can also specify an <code>:output</code> argument to a <code><a href="#LASS:LASS-FILE">lass-file</a></code> to specify what the target css file should be.</p> </div>  </article> <article id="copyright">  <h2>Copyright</h2> <span>lass</span> is licensed under the <span><a href="https://tldrlegal.com/search?q=Artistic">Artistic</a></span> license.  © <span>Nicolas Hafner &lt;shinmera@tymoon.eu&gt;</span> .  This library can be obtained on <a href="https://github.com/Shinmera/LASS">https://github.com/Shinmera/LASS</a>.  </article>  <article id="symbol-index"> <h2>Package Index</h2> <ul><li class="package"> <h3> <a name="LASS" href="#LASS">LASS</a> <span class="nicknames">(ORG.TYMOONNEXT.LASS)</span> </h3> <ul><li> <a name="LASS:*INDENT-LEVEL*"> </a> <article id="SPECIAL LASS:*INDENT-LEVEL*"> <header class="special"> <span class="type">special</span>  <h4 class="name"><code><a href="#SPECIAL%20LASS%3A%2AINDENT-LEVEL%2A">*INDENT-LEVEL*</a></code></h4>  </header> <div class="docstring"><pre>Directs the current amount of spaces used to indent.</pre></div> </article> </li><li> <a name="LASS:*PRETTY*"> </a> <article id="SPECIAL LASS:*PRETTY*"> <header class="special"> <span class="type">special</span>  <h4 class="name"><code><a href="#SPECIAL%20LASS%3A%2APRETTY%2A">*PRETTY*</a></code></h4>  </header> <div class="docstring"><pre>Directs whether to pretty-print using whitespace or not.</pre></div> </article> </li><li> <a name="LASS:*VARS*"> </a> <article id="SPECIAL LASS:*VARS*"> <header class="special"> <span class="type">special</span>  <h4 class="name"><code><a href="#SPECIAL%20LASS%3A%2AVARS%2A">*VARS*</a></code></h4>  </header> <div class="docstring"><pre>Special variable containing LASS-environment variables.

See <a href="http://l1sp.org/cl/the">the</a> definition of the LET block.</pre></div> </article> </li><li> <a name="LASS:LASS-FILE"> </a> <article id="CLASS LASS:LASS-FILE"> <header class="class"> <span class="type">class</span>  <h4 class="name"><code><a href="#CLASS%20LASS%3ALASS-FILE">LASS-FILE</a></code></h4>  </header> <div class="docstring"><pre>An ASDF source-file component to allow compilation of LASS to CSS in ASDF systems.</pre></div> </article> </li><li> <a name="LASS:PROPERTY-FUNCTION"> </a> <article id="ACCESSOR LASS:PROPERTY-FUNCTION"> <header class="accessor"> <span class="type">accessor</span>  <code>(</code><h4 class="name"><code><a href="#ACCESSOR%20LASS%3APROPERTY-FUNCTION">PROPERTY-FUNCTION</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME</code><code>)</code>  </header> <div class="docstring"><pre>Returns a function to process a property function of NAME, if any.</pre></div> </article> </li><li> <a name="LASS:COMPILE-AND-WRITE"> </a> <article id="FUNCTION LASS:COMPILE-AND-WRITE"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3ACOMPILE-AND-WRITE">COMPILE-AND-WRITE</a></code></h4> <code class="qualifiers"></code> <code class="arguments">&amp;REST FORMS</code><code>)</code>  </header> <div class="docstring"><pre>Shortcut for (WRITE-SHEET (COMPILE-SHEET FORMS*))</pre></div> </article> </li><li> <a name="LASS:COMPILE-SHEET"> </a> <article id="FUNCTION LASS:COMPILE-SHEET"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3ACOMPILE-SHEET">COMPILE-SHEET</a></code></h4> <code class="qualifiers"></code> <code class="arguments">&amp;REST BLOCKS</code><code>)</code>  </header> <div class="docstring"><pre>Compiles a LASS sheet composed of BLOCKS.
Each BLOCK is passed to COMPILE-BLOCK. The results thereof are appended
together into one list of blocks and properties.</pre></div> </article> </li><li> <a name="LASS:GENERATE"> </a> <article id="FUNCTION LASS:GENERATE"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3AGENERATE">GENERATE</a></code></h4> <code class="qualifiers"></code> <code class="arguments">IN &amp;KEY (OUT (MERGE-PATHNAMES (MAKE-PATHNAME :TYPE &quot;css&quot;) IN)) (PRETTY NIL)
 (IF-EXISTS :SUPERSEDE)</code><code>)</code>  </header> <div class="docstring"><pre>Generate a CSS file from a LASS file.

IN        --- The LASS input file. Has to be READable.
OUT       --- The target file, by default a file of same location and name, but with CSS type.
PRETTY    --- Whether to minify or not. See WRITE-SHEET.
IF-EXISTS --- See WITH-OPEN-FILE

Returns OUT</pre></div> </article> </li><li> <a name="LASS:INDENT"> </a> <article id="FUNCTION LASS:INDENT"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3AINDENT">INDENT</a></code></h4> <code class="qualifiers"></code> <code class="arguments"></code><code>)</code>  </header> <div class="docstring"><pre>Returns a string of the appropriate number of spaces depending on *PRETTY* and *INDENT-LEVEL*</pre></div> </article> </li><li> <a name="LASS:MAKE-BLOCK"> </a> <article id="FUNCTION LASS:MAKE-BLOCK"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3AMAKE-BLOCK">MAKE-BLOCK</a></code></h4> <code class="qualifiers"></code> <code class="arguments">SELECTOR VALUES</code><code>)</code>  </header> <div class="docstring"><pre>Creates a block object with SELECTOR and VALUES.</pre></div> </article> </li><li> <a name="LASS:MAKE-PROPERTY"> </a> <article id="FUNCTION LASS:MAKE-PROPERTY"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3AMAKE-PROPERTY">MAKE-PROPERTY</a></code></h4> <code class="qualifiers"></code> <code class="arguments">PROPERTY &amp;OPTIONAL VALUE</code><code>)</code>  </header> <div class="docstring"><pre>Creates a property object with PROPERTY as its key and VALUE as its value.</pre></div> </article> </li><li> <a name="LASS:REMOVE-PROPERTY-FUNCTION"> </a> <article id="FUNCTION LASS:REMOVE-PROPERTY-FUNCTION"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3AREMOVE-PROPERTY-FUNCTION">REMOVE-PROPERTY-FUNCTION</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME</code><code>)</code>  </header> <div class="docstring"><pre>Removes the property function NAME.</pre></div> </article> </li><li> <a name="LASS:RESOLVE-FUNCTION"> </a> <article id="FUNCTION LASS:RESOLVE-FUNCTION"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3ARESOLVE-FUNCTION">RESOLVE-FUNCTION</a></code></h4> <code class="qualifiers"></code> <code class="arguments">FUNCTION &amp;REST ARGS</code><code>)</code>  </header> <div class="docstring"><pre>Turns the FUNCTION with its ARGS into a properly usable property value.</pre></div> </article> </li><li> <a name="LASS:WRITE-SHEET"> </a> <article id="FUNCTION LASS:WRITE-SHEET"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3AWRITE-SHEET">WRITE-SHEET</a></code></h4> <code class="qualifiers"></code> <code class="arguments">SHEET &amp;KEY (STREAM NIL) (PRETTY *PRETTY*)</code><code>)</code>  </header> <div class="docstring"><pre>Writes the compiled SHEET object to STREAM.
If PRETTY is non-NIL, spaces and newlines are inserted as appropriate
in order to create a human-readable stylesheet. Otherwise whitespace is
only used where necessary, producing a minified version.

STREAM can be a STREAM, T for *STANDARD-OUTPUT*, or NIL for a STRING.</pre></div> </article> </li><li> <a name="LASS:WRITE-SHEET-PART"> </a> <article id="FUNCTION LASS:WRITE-SHEET-PART"> <header class="function"> <span class="type">function</span>  <code>(</code><h4 class="name"><code><a href="#FUNCTION%20LASS%3AWRITE-SHEET-PART">WRITE-SHEET-PART</a></code></h4> <code class="qualifiers"></code> <code class="arguments">STREAM BLOCK CP AP</code><code>)</code>  </header> <div class="docstring"><pre>Wrapper around WRITE-SHEET-OBJECT so that we can call it from FORMAT.
Calls WRITE-SHEET-OBJECT with (CAR BLOCK) (CDR BLOCK) STREAM.</pre></div> </article> </li><li> <a name="LASS:COMPILE-BLOCK"> </a> <article id="GENERIC LASS:COMPILE-BLOCK"> <header class="generic"> <span class="type">generic</span>  <code>(</code><h4 class="name"><code><a href="#GENERIC%20LASS%3ACOMPILE-BLOCK">COMPILE-BLOCK</a></code></h4> <code class="qualifiers"></code> <code class="arguments">HEADER FIELDS</code><code>)</code>  </header> <div class="docstring"><pre>Compiles the block with given HEADER and FIELDS list.
By default, the following case is handled:

 (T T)
Blocks are handled in the following way:
The HEADER is used as a selector and compiled through COMPILE-SELECTOR.
Fields are semantically segregated through KEYWORDS and LISTS.

Every time a KEYWORD is encountered, it is taken as the current property
and all following objects until either a LIST or a KEYWORD is encountered
are gathered as the property's values.

Every time a LIST is encountered, it is taken as a SUB-BLOCK and is
passed to COMPILE-BLOCK with the HEADER being the current block's
selector prepended to the selector of the sub-block.


Special handling of blocks may occur. 
See <a href="NIL">DEFINE-SPECIAL-BLOCK.</a></pre></div> </article> </li><li> <a name="LASS:COMPILE-CONSTRAINT"> </a> <article id="GENERIC LASS:COMPILE-CONSTRAINT"> <header class="generic"> <span class="type">generic</span>  <code>(</code><h4 class="name"><code><a href="#GENERIC%20LASS%3ACOMPILE-CONSTRAINT">COMPILE-CONSTRAINT</a></code></h4> <code class="qualifiers"></code> <code class="arguments">FUNC ARGS</code><code>)</code>  </header> <div class="docstring"><pre>Compiles a constraint of type FUNC with arguments ARGS to a list of alternative selectors.
By default, the following cases are handled:

 (T T)
Concatenates its ARGS together with spaces.
Preserves OR combinations.

 (NULL NULL)
Returns NIL

 (T NULL)
Returns FUNC

 (:OR T)
Passes all ARGS to COMPILE-SELECTOR individually and then APPENDS
all the results together.

 (:AND T)
Concatenates its ARGS together without spaces.
Preserves OR combinations.


Special handling of constraints may occur.
See <a href="NIL">DEFINE-SPECIAL-SELECTOR.</a></pre></div> </article> </li><li> <a name="LASS:COMPILE-PROPERTY"> </a> <article id="GENERIC LASS:COMPILE-PROPERTY"> <header class="generic"> <span class="type">generic</span>  <code>(</code><h4 class="name"><code><a href="#GENERIC%20LASS%3ACOMPILE-PROPERTY">COMPILE-PROPERTY</a></code></h4> <code class="qualifiers"></code> <code class="arguments">KEY VALUE</code><code>)</code>  </header> <div class="docstring"><pre>Compile a property of KEY and VALUE to a list of property objects.
By default, the following cases are handled:

 (T LIST)
A list is created with one property object, wherein the property-value is the
Space-concatenated list of RESOLVEd VALUEs. The KEY is DOWNCASEd.

 (T T)
A list is created with one property object, wherein the property-value is the
RESOLVEd VALUE. The KEY is DOWNCASEd.


Special handling of properties may occur.
See <a href="#LASS:DEFINE-SPECIAL-PROPERTY">DEFINE-SPECIAL-PROPERTY</a></pre></div> </article> </li><li> <a name="LASS:COMPILE-SELECTOR"> </a> <article id="GENERIC LASS:COMPILE-SELECTOR"> <header class="generic"> <span class="type">generic</span>  <code>(</code><h4 class="name"><code><a href="#GENERIC%20LASS%3ACOMPILE-SELECTOR">COMPILE-SELECTOR</a></code></h4> <code class="qualifiers"></code> <code class="arguments">SELECTOR</code><code>)</code>  </header> <div class="docstring"><pre>Compiles the SELECTOR form into a list of alternative selectors.
By default, the following cases are handled:

 (NULL)
Returns NIL.

 (LIST)
Calls COMPILE-CONSTRAINT with the SELECTOR's CAR and CDR.

 (T)
Returns a list with the RESOLVEd SELECTOR.</pre></div> </article> </li><li> <a name="LASS:CONSUME-ITEM"> </a> <article id="GENERIC LASS:CONSUME-ITEM"> <header class="generic"> <span class="type">generic</span>  <code>(</code><h4 class="name"><code><a href="#GENERIC%20LASS%3ACONSUME-ITEM">CONSUME-ITEM</a></code></h4> <code class="qualifiers"></code> <code class="arguments">ITEM READABLE-LIST</code><code>)</code>  </header> <div class="docstring"><pre>Consumes items from READABLE-LIST as required by the ITEM.
Returned should be two values, the first being a property to compile (or NIL)
and the second a block to compile (or NIL).
By default, the following cases are handled:

 (LIST)
Simply returns the ITEM as a block.

 (SYMBOL)
If it's a keyword, reads until the next keyword or list and returns that as a
property to compile. With property-functions, some sublists may also be read
in automatically. See DEFINE-PROPERTY-FUNCTION. If it is a regular symbol,
CALL-NEXT-METHOD is invoked.

 (T)
Signals an error.</pre></div> </article> </li><li> <a name="LASS:RESOLVE"> </a> <article id="GENERIC LASS:RESOLVE"> <header class="generic"> <span class="type">generic</span>  <code>(</code><h4 class="name"><code><a href="#GENERIC%20LASS%3ARESOLVE">RESOLVE</a></code></h4> <code class="qualifiers"></code> <code class="arguments">THING</code><code>)</code>  </header> <div class="docstring"><pre>Resolves THING to a value that makes sense for LASS.

By default the following types are handled:
NULL:     NIL
STRING:   the THING itself
ARRAY:    the variable stored in *VARS* under THING
KEYWORD:  Colon-prefixed, downcased symbol-name of THING
SYMBOL:   Downcased symbol-name of THING
PATHNAME: If designating an image, base64 encoded inline image data.
T:        PRINC-TO-STRING of THING</pre></div> </article> </li><li> <a name="LASS:WRITE-SHEET-OBJECT"> </a> <article id="GENERIC LASS:WRITE-SHEET-OBJECT"> <header class="generic"> <span class="type">generic</span>  <code>(</code><h4 class="name"><code><a href="#GENERIC%20LASS%3AWRITE-SHEET-OBJECT">WRITE-SHEET-OBJECT</a></code></h4> <code class="qualifiers"></code> <code class="arguments">TYPE OBJECT STREAM</code><code>)</code>  </header> <div class="docstring"><pre>Writes the OBJECT of type TYPE to STREAM.

By default the following TYPEs are handled:
 :BLOCK (SELECTOR-LIST OBJECTS*)
Prints the SELECTOR-LIST separated by commas, followed by an opening brace
and the printed list of OBJECTS using WRITE-SHEET-PART. Finally the body is
closed off with a closing brace. Newlines and spaces may be inserted where
necessary if *PRETTY* is non-NIL.

 :PROPERTY (KEY VALUE)
Prints the KEY. If VALUE is non-NIL, a colon is printed followed by the
VALUE. Finally a semicolon is printed. Spaces may be inserted where necessary
if *PRETTY* is non-NIL.</pre></div> </article> </li><li> <a name="LASS:DEFINE-BROWSER-PROPERTY"> </a> <article id="MACRO LASS:DEFINE-BROWSER-PROPERTY"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-BROWSER-PROPERTY">DEFINE-BROWSER-PROPERTY</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME ARGS &amp;BODY BROWSER-OPTIONS</code><code>)</code>  </header> <div class="docstring"><pre>Helper macro to define properties that have browser-dependant versions.

NAME            --- The base name of the property name or value.
ARGS            --- Property arguments, see DEFINE-SPECIAL-PROPERTY.
BROWSER-OPTIONS ::= (OPTION (symbol) FORM*)
OPTION          ::= :MOZ | :O | :WEBKIT | :MS | :W3C | :DEFAULT

Each browser-option body should return a single property. The SYMBOL
in the option definition is bound to the computed property name
 (eg -moz-NAME for the :MOZ option).
You can define special handling of the browsers by defining options
specifically for them. If no handling is defined, the DEFAULT option
is used as a fallback.</pre></div> </article> </li><li> <a name="LASS:DEFINE-PRIMITIVE-PROPERTY-CONSUMER"> </a> <article id="MACRO LASS:DEFINE-PRIMITIVE-PROPERTY-CONSUMER"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-PRIMITIVE-PROPERTY-CONSUMER">DEFINE-PRIMITIVE-PROPERTY-CONSUMER</a></code></h4> <code class="qualifiers"></code> <code class="arguments">SPECIALIZER (PROPVALS READABLE NEXT) &amp;BODY LOOP-BODY</code><code>)</code>  </header> <div class="docstring"><pre>Defines a CONSUME-ITEM method for the given item SPECIALIZER.

SPECIALIZER --- The method specializer for the item.
PROPVALS    --- The list that should contain the property values.
READABLE    --- The readable-list being operated on currently.
NEXT        --- Bound to the next (unconsumed) item in the readable-list.
LOOP-BODY   --- The body of the reading loop to execute until the readable is empty.

The return value of the loop-body is discarded. You can use (RETURN) to exit the loop,
for example for when you encounter an item you don't want to read.</pre></div> </article> </li><li> <a name="LASS:DEFINE-PROPERTY-FUNCTION"> </a> <article id="MACRO LASS:DEFINE-PROPERTY-FUNCTION"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-PROPERTY-FUNCTION">DEFINE-PROPERTY-FUNCTION</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME ARGS &amp;BODY BODY</code><code>)</code>  </header> <div class="docstring"><pre>Define a new property function NAME, accepting ARGS. 
The body should return a value to use directly, if possible a string.
The results of a property-function should not be RESOVLEd.

Property functions are function calls that occur as (part of) the
value of a property. Due to ambiguity issues with a general sub-block,
property functions need to be explicitly defined and may completely
differ depending on the property. Property functions defined with this
are only the defaults available for all properties. If you want to
minimise collision probability or avoid an illegal function for a
certain property, you should define a direct method on CONSUME-ITEM
to handle the reading of the property values manually.</pre></div> </article> </li><li> <a name="LASS:DEFINE-PROPERTY-FUNCTION-CASE"> </a> <article id="MACRO LASS:DEFINE-PROPERTY-FUNCTION-CASE"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-PROPERTY-FUNCTION-CASE">DEFINE-PROPERTY-FUNCTION-CASE</a></code></h4> <code class="qualifiers"></code> <code class="arguments">PROPERTY (ARGS) &amp;BODY FUNCTION-CLAUSES</code><code>)</code>  </header> <div class="docstring"><pre>Defines a CONSUME-ITEM method for PROPERTY that has special handling for property-functions.

FUNCTION-CLAUSES ::= function-clause*
FUNCTION-CLAUSE  ::= (function-name form*)

Each function-name is compared by STRING-EQUAL and each clause should return the
property-value to use in its place, or NIL if it should be skipped.

You can use (RETURN) in a clause body to stop reading values altogether.</pre></div> </article> </li><li> <a name="LASS:DEFINE-SIMPLE-PROPERTY-FUNCTION"> </a> <article id="MACRO LASS:DEFINE-SIMPLE-PROPERTY-FUNCTION"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-SIMPLE-PROPERTY-FUNCTION">DEFINE-SIMPLE-PROPERTY-FUNCTION</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME ARGS</code><code>)</code>  </header> <div class="docstring"><pre>Defines a property function that returns name(arg1,arg2...).
Only required arguments are allowed.</pre></div> </article> </li><li> <a name="LASS:DEFINE-SIMPLE-PROPERTY-FUNCTIONS"> </a> <article id="MACRO LASS:DEFINE-SIMPLE-PROPERTY-FUNCTIONS"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-SIMPLE-PROPERTY-FUNCTIONS">DEFINE-SIMPLE-PROPERTY-FUNCTIONS</a></code></h4> <code class="qualifiers"></code> <code class="arguments">PROPERTY &amp;REST FUNCSPECS</code><code>)</code>  </header> <div class="docstring"><pre>Defines a CONSUME-ITEM method for PROPERTY that has special handling for property-functions.

FUNCSPECS ::= funcspec*
FUNCSPEC  ::= (funcname arg* [&amp;optional arg*] [&amp;key arg*])

See <a href="NIL">DEFINE-PROPERTY-FUNCTION-CASE.</a></pre></div> </article> </li><li> <a name="LASS:DEFINE-SINGLE-ARG-SELECTOR"> </a> <article id="MACRO LASS:DEFINE-SINGLE-ARG-SELECTOR"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-SINGLE-ARG-SELECTOR">DEFINE-SINGLE-ARG-SELECTOR</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME</code><code>)</code>  </header> <div class="docstring"><pre>Helper macro to define a single-argument pseudo-selector like NOT or NTH-CHILD.</pre></div> </article> </li><li> <a name="LASS:DEFINE-SPECIAL-BLOCK"> </a> <article id="MACRO LASS:DEFINE-SPECIAL-BLOCK"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-SPECIAL-BLOCK">DEFINE-SPECIAL-BLOCK</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME ARGS &amp;BODY BODY</code><code>)</code>  </header> <div class="docstring"><pre>Define handling of a special block type.
In order for the block to be recognised, it has to begin with the NAME as a keyword.
The ARGS is a lambda-list that parses the block contents.

Expected as a return value is a /list/ of either attributes or blocks.

See <a href="#LASS:COMPILE-BLOCK">COMPILE-BLOCK</a></pre></div> </article> </li><li> <a name="LASS:DEFINE-SPECIAL-PROPERTY"> </a> <article id="MACRO LASS:DEFINE-SPECIAL-PROPERTY"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-SPECIAL-PROPERTY">DEFINE-SPECIAL-PROPERTY</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME ARGS &amp;BODY BODY</code><code>)</code>  </header> <div class="docstring"><pre>Define handling of a special property.
The ARGS is a lambda-list that parses the arguments passed to the property.

Expected as a return value is a /list/ of either attributes or blocks.

See <a href="#LASS:COMPILE-PROPERTY">COMPILE-PROPERTY</a></pre></div> </article> </li><li> <a name="LASS:DEFINE-SPECIAL-SELECTOR"> </a> <article id="MACRO LASS:DEFINE-SPECIAL-SELECTOR"> <header class="macro"> <span class="type">macro</span>  <code>(</code><h4 class="name"><code><a href="#MACRO%20LASS%3ADEFINE-SPECIAL-SELECTOR">DEFINE-SPECIAL-SELECTOR</a></code></h4> <code class="qualifiers"></code> <code class="arguments">NAME ARGS &amp;BODY BODY</code><code>)</code>  </header> <div class="docstring"><pre>Define handling of a special selector type.
In order for the selector to be recognised, it has to begin with the NAME as a keyword.
The ARGS is a lambda-list that parses the selector contents.

Expected as a return value is a /list/ of alternate versions of selectors.

See <a href="NIL">COMPILE-CONSTRAINT.</a></pre></div> </article> </li></ul> </li></ul> </article>  </main> </body> </html> 